package org.testis.testdriver;

import org.testis.testdriver.exceptions.NoSuchTestPartChildExists;
import org.testis.data.TestStepResultType;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Vector;

public class TestPlanBuilder implements ITestBuilder {

    private TestPart motherTestPart;
    protected Vector<String> m_ExceptionCollection;

    public TestPlanBuilder() {
        m_ExceptionCollection = new Vector<String>();
    }

    public TestPart getResult() {
        return motherTestPart;
    }

    public void buildTestSuite(String testSuiteId,
            String testSuiteName,
            String testSuiteDescription) {
        motherTestPart =
                new StepContainer(testSuiteId,
                testSuiteName,
                testSuiteDescription,
                AtofEnumaration.TestPartType.TestSuite);
    }

    public void buildTestPart(String testPartId,
            String testPartName,
            String testPartDesc,
            AtofEnumaration.TestPartType containerType,
            String parentTestPartId) {
        TestPart testPart = getTestPartFromId(parentTestPartId);

        StepContainer ourContainer = new StepContainer(testPartId,
                testPartName,
                testPartDesc,
                containerType);
        testPart.add(ourContainer);


    }

    public void setTestCaseThreading(String testPartId,
            int invokeCount,
            int noOfThreads) {
        StepContainer testPart = (StepContainer) getTestPartFromId(testPartId);

        testPart.setTestCaseParameters(invokeCount,
                noOfThreads,
                testPart.getActivateImpossibleSuccessPercFeature());
    }

    public void setTestCaseRetyrOnFail(String testPartId,
            int noOfRetryOnFail) {
        StepContainer testPart = (StepContainer) getTestPartFromId(testPartId);

        testPart.setRetryOnFailCount(noOfRetryOnFail);


    }

    public void setTestPartDependency(String testPartId,
            String[] depParts,
            boolean runAlways) {
        StepContainer testPart = (StepContainer) getTestPartFromId(testPartId);

        testPart.setTestPartDependency(depParts,
                runAlways);
    }

    public void setTestCaseSuccessPerc(String testPartId,
            short successPercentage) {
        StepContainer testPart = (StepContainer) getTestPartFromId(testPartId);

        testPart.setCaseSuccessPercentage(successPercentage);
    }

    public void setTestPlanDutRunTime(String testPartId,
            String versDutFw,
            String dutName,
            String browserType,
            int browserSpeed,
            String currentIp,
            String testBedIp) {
        StepContainer testPlan = (StepContainer) getTestPartFromId(testPartId);

        testPlan.setTestPlanDutParameters(versDutFw,
                dutName,
                browserType,
                browserSpeed,
                currentIp,
                testBedIp);


    }

    public void setTestPlanTestPcRunTime(String testPartId,
            String versATOF,
            String testPcMacAddr) {
        StepContainer testPlan = (StepContainer) getTestPartFromId(testPartId);

        testPlan.setTestPlanTestPcParameters(versATOF,
                testPcMacAddr);
    }

    public void setTestPlanGlobals(String testPartId,
            Integer deviceLangId,
            Integer globalProId) {
        StepContainer testPlan = (StepContainer) getTestPartFromId(testPartId);

        testPlan.setTestPlanGlobals(deviceLangId,
                globalProId);
    }

    public void setTestPlanDutSerial(String testPartId,
            HashMap<String, String> dutSerialConf) {
        StepContainer testPlan = (StepContainer) getTestPartFromId(testPartId);

        testPlan.setSerialConnData(dutSerialConf);
    }

    public void setIsCriticalPart(String testPartId,
            boolean isCritical) {
        TestPart testPart = getTestPartFromId(testPartId);

        testPart.setIsCritical(isCritical);
    }

    public void buildTestStep(String testStepId,
            String testStepName,
            String partDescription,
            String parentTestPart) {
        TestPart testPart = getTestPartFromId(parentTestPart);
        testPart.add(new TestStep(testStepId,
                testStepName,
                partDescription));
    }

    public void setTestStepParam(String testStepId,
            String testPcMacAddress,
            AtofEnumaration.AtofModule moduleName,
            String actName,
            String[] supportedDevices,String storePostfix) {
        TestStep testStep = (TestStep) getTestPartFromId(testStepId);

        testStep.setTestStepParams(testPcMacAddress,
                moduleName,
                actName,
                supportedDevices);
        testStep.setStoreResultPostfix(storePostfix);
    }

    public void setTestStepRunTime(String testStepId,
            int timeOut,            
            int delayTime,
            int delayTimeAfterExecute,
            int noOfRetryOnFail,
            boolean isAsynch,
            boolean dataArrayAppliesToCase,
            boolean isCritical) {
        TestStep testStep = (TestStep) getTestPartFromId(testStepId);
        testStep.setTestStepRunTime(timeOut,                
                delayTime,
                delayTimeAfterExecute,
                noOfRetryOnFail,
                isAsynch,
                dataArrayAppliesToCase,
                isCritical);
    }

    public void setTestStepGroupRunTime(String testStepGroupId,
            int noOfRetryOnFail,
            boolean isCritical) {
        StepContainer testStepGroup = (StepContainer) getTestPartFromId(
                testStepGroupId);
        testStepGroup.setIsCritical(isCritical);
        testStepGroup.setRetryOnFailCount(noOfRetryOnFail);

    }

    public void setTestStepSuccessPerc(String testStepId,
            short successPercentage) {
        TestStep testStep = (TestStep) getTestPartFromId(testStepId);
        testStep.setM_Step_SuccessPercentage(successPercentage);
    }

    public void setTestStepModuleParams(String testStepId,
            LinkedHashMap<String, String> degers) {
        TestStep testStep = (TestStep) getTestPartFromId(testStepId);
        testStep.setModuleParams(degers);
    }

    public void attachDataToStep(String dataObjId,
            String dataObjName,
            TestStepResultType expResult,
            LinkedHashMap<String, String> dataPairs,
            LinkedList<String> conditions,
            String testStepToAttach) {

        TestPart testPart = getTestPartFromId(testStepToAttach);
        TestDataObject dataToAttach = new TestDataObject(dataObjId,
                dataObjName,
                expResult,
                dataPairs,
                conditions);


        ((TestStep) testPart).addTestStepData(dataToAttach);


    }

    public void setTestPartConditions(String testPartId,
            LinkedList<String> conditions) {
        TestPart testPart = getTestPartFromId(testPartId);
        testPart.setConditions(conditions);

    }

    /**
     * This is the method used to find and return a TestPart by giving its TestPart id.
     * @param testPartId The id of the TestPart     
     */
    public TestPart getTestPartFromId(String testPartId) {

        return findTestPart(motherTestPart,
                testPartId);

    }

    /**
     * This is the method used to find and return a TestPart by giving its TestPart id
     * and the current TestPart object.
     * @param rootPart current TestPart     
     * @param testPartId The id of the TestPart
     */
    private TestPart findTestPart(TestPart rootPart,
            String testPartId) {

        TestIterator innerIter = rootPart.createIter();
        if (rootPart.getPartId().equals(testPartId)) {
            return rootPart;
        } else {
            if (innerIter != null) {
                innerIter.init();
                while (innerIter.isDone()) {
                    innerIter.next();
                    TestPart refr = null;
                    try {
                        refr = findTestPart(innerIter.currentItem(),
                                testPartId);
                    } catch (RuntimeException eee) {
                    }
                    if (refr != null) {
                        return refr;
                    }

                }

                throw new NoSuchTestPartChildExists("No Test Part named "
                        + testPartId + " exists.");
            } else {
                throw new RuntimeException("Null Iterator returned from "
                        + rootPart.getPartName());
            }
        }
    }

    public Vector<String> getExceptions() {
        return m_ExceptionCollection;
    }

    public void pushExceptionMessage(String transexception) {
        this.m_ExceptionCollection.add(transexception);
    }

    public void resetExceptions() {
        this.m_ExceptionCollection.clear();
    }
}

